licenseHasExpired
Email Templatesโ
| License Expired | Grace Period Expired |
|---|---|
![]() | ![]() |
| 30 Days Warning | 60 Days Warning |
|---|---|
![]() | ![]() |
- ๐ฌ๐ง English
- ๐ฎ๐น Italian
Function Names: licenseHasExpired / testLicenseHasExpired
Trigger: Scheduler (onSchedule - daily at 18:00) / HTTPS (onRequest)
Purpose: Daily notification system for license management in ARShades Subscription System. This Cloud Function checks licenses daily and sends notifications to clients at key moments. It uses ZeptoMail as the primary email system and Nodemailer as fallback with specific templates for different notification types.
Detailed Functionalityโ
1. TRIGGER AND SCHEDULINGโ
- Automatic execution daily at 18:00 (Europe/Rome timezone)
- Can be executed manually via HTTP endpoint for testing
- Execution region: europe-central2
2. LICENSE RETRIEVAL AND ANALYSISโ
- Queries 'ARShadesSubscriptions' collection for all licenses
- Filters only licenses with "Active" or "Expired" status
- Verifies presence of valid expiration date
- Handles different timestamp formats for expiration date
- Calculates remaining days until expiration
3. PRELIMINARY OPTIMIZATIONโ
- Checks if notifications need to be sent BEFORE expensive database queries
- Verifies if license is at 60 days, 30 days from expiration, just expired, or 15 days after expiration
- Skips processing if no notification is needed
4. NOTIFICATION TYPESโ
a. 60 Days Warning (SixtyDaysWarning)
- Sent when exactly 60 days remain until expiration
- Template: SIXTY_DAYS
b. 30 Days Warning (ThirtyDaysWarning)
- Sent when exactly 30 days remain until expiration
- Template: THIRTY_DAYS
c. Expiration Notification (Expired)
- Sent when license expires (endDate reached)
- Updates license status to 'Expired'
- Template: EXPIRED
d. Grace Period End Notification (GracePeriodEnd)
- Sent 15 days after expiration
- Verifies that status is 'Expired'
- Template: GRACE_PERIOD_END
5. PRELIMINARY CHECKSโ
- Verifies if email sending is blocked (blockSendMail = true)
- Checks if notification of same type was already sent
- Verifies presence of client reference (clientRef)
6. CLIENT DATA AND PROFILES RETRIEVALโ
- Retrieves client document from 'Client' collection
- Gets list of catalogs associated with license (supports different storage formats)
- Extracts associated profiles (allProfileList and mainProfileList)
7. EMAIL RECIPIENTS SELECTION (UPDATED LOGIC)โ
- For each profile in allProfileList, verifies access to license catalogs
- IMPORTANT: Selects ONLY profiles with 'Cliente' role (excludes Admin, etc.)
- Verifies intersection between profile catalogs and license catalogs
- NEW LOGIC: If no profile has specific access BUT profiles exist in mainProfileList, email is still sent
- SKIPS ONLY if: profilesWithAccess.length === 0 AND mainProfileList.length === 0
- Logs debug details for each analyzed profile
- Handles errors for profiles not found or not accessible
8. EMAIL DATA PREPARATIONโ
- Formats expiration and grace period dates in Italian format
- Retrieves main profile information for personalization
- Prepares TO (profiles with access), CC (main profiles) and BCC (admin) recipients
- FIX APPLIED: Resolved licenseName/formattedLicenseName variable scoping conflict
9. EMAIL SENDING WITH ZEPTOMAILโ
- Uses appropriate template for each notification type
- Passes necessary variables to template (license name, main profile, dates)
- Handles TO, CC and BCC with full names when available
10. IMPROVED FALLBACK HANDLINGโ
- In case of ZeptoMail error, uses Nodemailer with specific templates for each notification type
- NEW FALLBACK TEMPLATES:
- SixtyDaysWarning: "Warning: License will expire in 60 days" (orange)
- ThirtyDaysWarning: "Urgent: License will expire in 30 days" (dark orange)
- Expired: "EXPIRED: License expired today" (red, with grace period info)
- GracePeriodEnd: "CRITICAL: Grace period ended" (dark red, service suspended)
- Professional HTML templates with appropriate colors and clean layout
- Correct dates and content for each scenario (future expiration vs already expired)
- Sent only to profiles in mainProfileList
- Logs errors from both main system and fallback
11. LICENSE DOCUMENT UPDATEโ
- After successful sending, updates 'notifications' array
- Adds new object with specific notification type and sendDate
- If expiration notification, also updates status to 'Expired'
12. ADVANCED LOGGING AND MONITORINGโ
- Logs complete details of each process phase
- Tracks successes, errors and fallback attempts
- Produces categorized final summary (emails sent, no action, skipped, etc.)
- Provides aggregate statistics by result type
Input (Payload)โ
Scheduler Function (licenseHasExpired)โ
- Automatic trigger: No input required (scheduled execution)
- Schedule: Daily at 18:00 Europe/Rome timezone
HTTP Function (testLicenseHasExpired)โ
- Method: GET
- Headers: None required
- Body: None required
- Parameters: None required
Output (Success)โ
Scheduler Functionโ
{
"success": true,
"processed": true,
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true
}
]
}
HTTP Functionโ
{
"success": true,
"message": "Controllo licenze scadute completato con successo",
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true,
"fallback": false
}
]
}
Response Properties:
success(boolean): Indicates if the operation was completed successfullymessage(string): Descriptive message about the operation resultresults(array): Array of processed licenses with detailslicenseId(string): Unique identifier of the processed licenselicenseName(string): Name and type of the licenserecipients(array): List of email addresses that received the notificationfallback(boolean): Indicates if Nodemailer fallback was used
Testingโ
URL (if HTTPS)โ
Development: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired
Test with Emulatorโ
-
Start Firebase emulators:
firebase emulators:start --only functions -
Set Node.js version:
nvm use 20 -
Test with curl:
curl "http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired"
Postman Testingโ
- Method: GET
- URL:
http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired - Headers: None required
- Body: None required
Deploy Commandโ
firebase deploy --only functions:licenseHasExpired,functions:testLicenseHasExpired
Production URLโ
Scheduled Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/licenseHasExpired (Reference only - not directly callable)
Test Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/testLicenseHasExpired
MAIL_TEMPLATE_KEYSโ
- EXPIRED:
13ef.8598f19fbcc5adb.k1.9902c130-46a8-11f0-900d-dad70ff08860.1975e5ffcc38 - SIXTY_DAYS:
13ef.8598f19fbcc5adb.k1.c7e1eee0-46d0-11f0-900d-dad70ff08860.1975f6754ce - THIRTY_DAYS:
13ef.8598f19fbcc5adb.k1.dec244d1-46d4-11f0-900d-dad70ff08860.1975f82218d - GRACE_PERIOD_END:
13ef.8598f19fbcc5adb.k1.13d51510-46d7-11f0-900d-dad70ff08860.1975f9098e1
Function Names: licenseHasExpired / testLicenseHasExpired
Trigger: Scheduler (onSchedule - giornaliero alle 18:00) / HTTPS (onRequest)
Purpose: Sistema di notifica giornaliero per la gestione delle licenze nel ARShades Subscription System. Questa Cloud Function controlla giornalmente le licenze e invia notifiche ai clienti in momenti chiave. Utilizza ZeptoMail come sistema di email principale e Nodemailer come fallback con template specifici per diversi tipi di notifica.
Funzionamento Dettagliatoโ
1. TRIGGER E SCHEDULINGโ
- Esecuzione automatica giornaliera alle 18:00 (fuso orario Europe/Rome)
- Puรฒ essere eseguita manualmente tramite endpoint HTTP per test
- Regione di esecuzione: europe-central2
2. RECUPERO E ANALISI LICENZEโ
- Interroga la collezione 'ARShadesSubscriptions' per tutte le licenze
- Filtra solo licenze con status "Active" o "Expired"
- Verifica la presenza di una data di scadenza valida
- Gestisce diversi formati di timestamp per la data di scadenza
- Calcola i giorni rimanenti fino alla scadenza
3. OTTIMIZZAZIONE PRELIMINAREโ
- Verifica se รจ necessario inviare notifiche PRIMA di fare query costose al database
- Controlla se la licenza รจ a 60 giorni, 30 giorni dalla scadenza, appena scaduta o a 15 giorni dopo la scadenza
- Salta l'elaborazione se non รจ necessaria alcuna notifica
4. TIPI DI NOTIFICAโ
a. Notifica 60 giorni prima della scadenza (SixtyDaysWarning)
- Inviata quando mancano esattamente 60 giorni alla scadenza
- Template: SIXTY_DAYS
b. Notifica 30 giorni prima della scadenza (ThirtyDaysWarning)
- Inviata quando mancano esattamente 30 giorni alla scadenza
- Template: THIRTY_DAYS
c. Notifica di scadenza (Expired)
- Inviata quando la licenza scade (endDate raggiunta)
- Aggiorna lo status della licenza a 'Expired'
- Template: EXPIRED
d. Notifica fine periodo di grazia (GracePeriodEnd)
- Inviata 15 giorni dopo la scadenza
- Verifica che lo status sia 'Expired'
- Template: GRACE_PERIOD_END
5. CONTROLLI PRELIMINARIโ
- Verifica se l'invio delle email รจ bloccato (blockSendMail = true)
- Controlla se รจ giร stata inviata una notifica dello stesso tipo
- Verifica la presenza del riferimento al cliente (clientRef)
6. RECUPERO DATI CLIENTE E PROFILIโ
- Recupera il documento cliente da 'Client'
- Ottiene la lista dei cataloghi associati alla licenza (supporta diversi formati di memorizzazione)
- Estrae i profili associati (allProfileList e mainProfileList)
7. SELEZIONE DESTINATARI EMAIL (LOGICA AGGIORNATA)โ
- Per ogni profilo in allProfileList, verifica l'accesso ai cataloghi della licenza
- IMPORTANTE: Seleziona SOLO i profili con ruolo 'Cliente' (esclude Admin, ecc.)
- Verifica l'intersezione tra i cataloghi del profilo e quelli della licenza
- NUOVA LOGICA: Se nessun profilo ha accesso specifico MA esistono profili in mainProfileList, l'email viene comunque inviata
- SALTA SOLO se: profilesWithAccess.length === 0 AND mainProfileList.length === 0
- Registra dettagli di debug per ogni profilo analizzato
- Gestisce errori per profili non trovati o non accessibili
8. PREPARAZIONE DATI EMAILโ
- Formatta le date di scadenza e periodo di grazia in formato italiano
- Recupera informazioni del profilo principale per personalizzazione
- Prepara destinatari TO (profili con accesso), CC (profili principali) e BCC (admin)
- FIX APPLICATO: Risolto conflitto di scoping della variabile licenseName/formattedLicenseName
9. INVIO EMAIL CON ZEPTOMAILโ
- Utilizza il template appropriato per ogni tipo di notifica
- Passa le variabili necessarie al template (nome licenza, profilo principale, date)
- Gestisce TO, CC e BCC con nomi completi quando disponibili
10. GESTIONE FALLBACK MIGLIORATAโ
- In caso di errore con ZeptoMail, utilizza Nodemailer con template specifici per ogni tipo di notifica
- NUOVI TEMPLATE FALLBACK:
- SixtyDaysWarning: "Avviso: La licenza scadrร tra 60 giorni" (arancione)
- ThirtyDaysWarning: "Urgente: La licenza scadrร tra 30 giorni" (arancione scuro)
- Expired: "SCADUTA: La licenza รจ scaduta oggi" (rosso, con info periodo di grazia)
- GracePeriodEnd: "CRITICO: Periodo di grazia terminato" (rosso scuro, servizio sospeso)
- Template HTML professionali con colori appropriati e layout pulito
- Date e contenuti corretti per ogni scenario (scadenza futura vs giร scaduta)
- Viene inviata solo ai profili in mainProfileList
- Registra errori sia del sistema principale che del fallback
11. AGGIORNAMENTO DOCUMENTO LICENZAโ
- Dopo l'invio con successo, aggiorna l'array 'notifications'
- Aggiunge un nuovo oggetto con il tipo specifico di notifica e sendDate
- Se รจ una notifica di scadenza, aggiorna anche lo status a 'Expired'
12. LOGGING E MONITORAGGIO AVANZATOโ
- Registra dettagli completi di ogni fase del processo
- Traccia successi, errori e tentativi di fallback
- Produce un riepilogo finale categorizzato (email inviate, nessuna azione, saltate, ecc.)
- Fornisce statistiche aggregate per tipo di risultato
Input (Payload)โ
Funzione Scheduler (licenseHasExpired)โ
- Trigger automatico: Nessun input richiesto (esecuzione pianificata)
- Schedule: Giornaliero alle 18:00 fuso orario Europe/Rome
Funzione HTTP (testLicenseHasExpired)โ
- Metodo: GET
- Headers: Nessuno richiesto
- Body: Nessuno richiesto
- Parametri: Nessuno richiesto
Output (Successo)โ
Funzione Schedulerโ
{
"success": true,
"processed": true,
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true
}
]
}
Funzione HTTPโ
{
"success": true,
"message": "Controllo licenze scadute completato con successo",
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true,
"fallback": false
}
]
}
Proprietร Risposta:
success(boolean): Indica se l'operazione รจ stata completata con successomessage(string): Messaggio descrittivo sul risultato dell'operazioneresults(array): Array delle licenze elaborate con dettaglilicenseId(string): Identificatore unico della licenza elaboratalicenseName(string): Nome e tipo della licenzarecipients(array): Lista degli indirizzi email che hanno ricevuto la notificafallback(boolean): Indica se รจ stato utilizzato il fallback Nodemailer
Testingโ
URL (if HTTPS)โ
Development: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired
Test con Emulatorโ
-
Avvia gli emulatori Firebase:
firebase emulators:start --only functions -
Imposta la versione Node.js:
nvm use 20 -
Test con curl:
curl "http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired"
Test Postmanโ
- Metodo: GET
- URL:
http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired - Headers: Nessuno richiesto
- Body: Nessuno richiesto
Deploy Commandโ
firebase deploy --only functions:licenseHasExpired,functions:testLicenseHasExpired
Production URLโ
Funzione Schedulata: https://europe-central2-arshades-7e18a.cloudfunctions.net/licenseHasExpired (Solo riferimento - non direttamente chiamabile)
Funzione Test: https://europe-central2-arshades-7e18a.cloudfunctions.net/testLicenseHasExpired
MAIL_TEMPLATE_KEYSโ
- EXPIRED:
13ef.8598f19fbcc5adb.k1.9902c130-46a8-11f0-900d-dad70ff08860.1975e5ffcc38 - SIXTY_DAYS:
13ef.8598f19fbcc5adb.k1.c7e1eee0-46d0-11f0-900d-dad70ff08860.1975f6754ce - THIRTY_DAYS:
13ef.8598f19fbcc5adb.k1.dec244d1-46d4-11f0-900d-dad70ff08860.1975f82218d - GRACE_PERIOD_END:
13ef.8598f19fbcc5adb.k1.13d51510-46d7-11f0-900d-dad70ff08860.1975f9098e1



